package com.bxd.baodan.update;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast;

import com.bxd.baodan.R;


import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class DownloadService extends Service {
	private NotificationManager notificationMrg;
	public static final int TYPE_INSURE_HELPER = 1;
	public static Map<String, MyThread> threadcache = new HashMap<String, MyThread>();
	private Holder holder;
	String apkurl, flag_string;
	Notification notification;

	private ConnectivityManager connectivityManager;
	private NetworkInfo info;

	public void onCreate() {
		super.onCreate();
		notificationMrg = (NotificationManager) this
				.getSystemService(Context.NOTIFICATION_SERVICE);

		// 注册网络监听接收器
		IntentFilter mFilter = new IntentFilter();
		mFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
		mFilter.addAction("android.basic.notification.click.pause");
		mFilter.addAction("android.basic.notification.click.cancel");
		mFilter.addAction("android.basic.notification.click.restart");
		this.registerReceiver(stateReceiver, mFilter);
		// 注册任务广播接收器

	}

	@SuppressWarnings({ "null", "deprecation" })
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		super.onStartCommand(intent, flags, startId);
		apkurl = intent.getStringExtra(UpdateConstants.UPDATE_DOWNLOAD);
		flag_string = intent.getStringExtra("flag_string");
		notification = new Notification(R.drawable.logo_icon, "下载进度",
				System.currentTimeMillis());// 设定Notification出现时的声音，一般不建议自定义
		// System.currentTimeMillis()
		notification.flags = Notification.FLAG_ONGOING_EVENT
				| Notification.FLAG_NO_CLEAR;// 出现在 “正在运行的”栏目下面
		// notification.flags |= Notification.FLAG_NO_CLEAR;// 标题栏默认清除按钮失效
		RemoteViews contentView1 = new RemoteViews(getPackageName(),
				R.layout.notification_version);
		contentView1.setTextViewText(R.id.n_title, "准备下载");
		contentView1.setTextViewText(R.id.n_text, 0 + "% ");
		contentView1.setProgressBar(R.id.n_progress, 100, 0, false);
		notification.contentView = contentView1;

		return START_REDELIVER_INTENT;
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		try {
			this.unregisterReceiver(stateReceiver);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	// 状态栏视图更新
	private Notification displayNotificationMessage(Notification notification,
			int count, int flag, String url, String filename) {
		// notification.contentIntent = receiveMsmIntent(flag, url);
		RemoteViews contentView1 = notification.contentView;
		contentView1.setTextViewText(R.id.n_title, filename);
		contentView1.setTextViewText(R.id.n_text, count + "% ");
		contentView1.setProgressBar(R.id.n_progress, 100, count, false);
		notification.contentView = contentView1;
		// 提交一个通知在状态栏中显示。如果拥有相同标签和相同id的通知已经被提交而且没有被移除，该方法会用更新的信息来替换之前的通知。
		notificationMrg.notify(flag, notification);
		return notification;

	}

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	private void sendMsg(int what, int c, String url,
			Notification notification, int flag, Uri uri, String filename,
			boolean changer) {
		Message msg = new Message();
		msg.what = what;// 用来识别发送消息的类型
		msg.arg1 = 0;
		holder = new Holder();
		holder.count = c;
		holder.url = url;
		holder.flag = flag;
		holder.notify = notification;
		holder.Uri = uri;
		holder.filename = filename;
		holder.changer = changer;
		msg.obj = holder;// 消息传递的自定义对象信息
		handler.sendMessage(msg);
	}

	// 定义一个Handler，用于处理下载线程与主线程间通讯
	private Handler handler = new Handler(new Handler.Callback() {
		@Override
		public boolean handleMessage(Message msg) {
			final Holder data = (Holder) msg.obj;
			if (!Thread.currentThread().isInterrupted()) {
				// 判断下载线程是否中断
				switch (msg.what) {
					case 1:
						if (data.count >= 99) {
							notificationMrg.cancel(data.flag);
							break;
						}

						if (threadcache.containsKey(data.url)) {
							// 每次更新时，先以key，扫描hashmap，存在则读取出来。
							Notification notification;
							MyThread thread;
							thread = threadcache.get(data.url);
							notification = thread.notification;
							notification = displayNotificationMessage(notification,
									data.count, data.flag, data.url, data.filename);
							thread.notification = notification;
							threadcache.put(data.url, thread);
						}
						break;
					case 2:
						if (data.changer) {
							openfile(data.Uri);
						} else {
							Log.i("avi", "取消下载");
							Toast.makeText(getApplicationContext(),
									data.filename + "下载取消", Toast.LENGTH_SHORT).show();
						}
						threadcache.remove(data.url);
						Intent cancel = new Intent()
								.setAction("android.basic.button.click.cancel");
						cancel.putExtra("url", data.url);
						sendBroadcast(cancel);
						onDestroy();
						break;
					case -1:
						String error = msg.getData().getString("error");
						Toast.makeText(getApplication(), data.filename + "下载失败",
								Toast.LENGTH_LONG).show();
						Intent cancel2 = new Intent()
								.setAction("android.basic.button.click.cancel");
						cancel2.putExtra("url", data.url);
						sendBroadcast(cancel2);
						break;
					// 否则输出错误提示
				}
			}
			return false;
		}
	}) ;

	public void openfile(Uri url) {
		Intent intent = new Intent(Intent.ACTION_VIEW);
		// 区别于默认优先启动在activity栈中已经存在的activity（如果之前启动过，并还没有被destroy的话）而是无论是否存在，都重新启动新的activity
		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		intent.setDataAndType(url, "application/vnd.android.package-archive");
		startActivity(intent);
		this.stopSelf();
	}

	public class Holder {
		Notification notify;
		String url;
		int count;
		int flag;
		Uri Uri;
		String filename;
		boolean changer;
	}

	private BroadcastReceiver stateReceiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();

			if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
				Log.d("mark", "网络状态已经改变");
				connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
				info = connectivityManager.getActiveNetworkInfo();
				if (info != null && info.isAvailable()) {
					String name = info.getTypeName();
					Log.d("mark", "当前网络名称：" + name);
					try {
						if (flag_string.equals("DownloadService")) {
							final MyThread thread = new MyThread(notification,
									apkurl, 2);
							thread.setchanger(true);
							threadcache.put(apkurl, thread);
							thread.start();
						}
					} catch (Exception e) {
						// TODO: handle exception
					}

				} else {
					Log.d("mark", "没有可用网络,下载服务停止");
					Intent pause = new Intent()
							.setAction("android.basic.notification.click.pause");
					Bundle bundel2 = new Bundle();
					bundel2.putInt("flag", 2);
					pause.putExtras(bundel2);
					pause.putExtra("url", apkurl);
					sendBroadcast(pause);
				}
			}

			if (action.equals("android.basic.notification.click.cancel")) {
				Bundle bundle = intent.getExtras();
				int m = bundle.getInt("flag");
				String url = intent.getStringExtra("url");
				notificationMrg.cancel(m);
				if (threadcache.containsKey(url)) {
					MyThread onethread = threadcache.get(url);
					onethread.setchanger(false);
				}
			}

			if (action.equals("android.basic.notification.click.pause")) {
				Bundle bundle = intent.getExtras();
				int m = bundle.getInt("flag");
				String url = intent.getStringExtra("url");
				// notificationMrg.cancel(m);
				if (threadcache.containsKey(url)) {
					MyThread onethread = threadcache.get(url);
					onethread.setSuspend(true);
					// 当前线程暂停/ 等待
				}
			}

			if (action.equals("android.basic.notification.click.restart")) {
				Bundle bundle = intent.getExtras();
				int m = bundle.getInt("flag");
				String url = intent.getStringExtra("url");
				// notificationMrg.cancel(m);
				if (threadcache.containsKey(url)) {
					MyThread onethread = threadcache.get(url);
					onethread.setSuspend(false);
					// 调用setSuspend(false)让当前线程恢复/唤醒
				}
			}
		}
	};


	public class MyThread extends Thread {
		private boolean changer;
		private String url;
		private int flag;
		private boolean suspend = false;
		private String control = ""; // 只是需要一个对象而已，这个对象没有实际意义
		private Notification notification;
		int load;

		public MyThread(Notification notification, String apkurl, int notifyflag) {
			super();
			this.notification = notification;
			this.url = apkurl;
			this.flag = notifyflag;
		}

		public void run() {
			String url = geturl();
			int flag = getflag();
			String filename;
			int first = url.lastIndexOf("/") + 1;
			filename = url.substring(first, url.length()).toLowerCase();
			double m = 0.0;
			try {
				OkHttpClient client = new OkHttpClient();
				final Request request = new Request.Builder().url(url).build();
				Call call = client.newCall(request);
				Response response = call.execute();
				InputStream is = response.body().byteStream();
				double length=	response.body().contentLength();
				// 使用InputStream对文件进行读取，就是字节流的输入
				FileOutputStream fileOutputStream = null;
				File file = null;
				if (is != null && getchanger()) {
					file = new File(Environment.getExternalStorageDirectory(),
							filename);
					fileOutputStream = new FileOutputStream(file);
					byte[] buf = new byte[1024];
					int ch = -1;
					float count = 0;
					// ch中存放从buf字节数组中读取到的字节个数
					while ((ch = is.read(buf)) != -1 && getchanger()) {

						synchronized (control) {
							if (getSuspend()) {
								try {
									Intent pause = new Intent()
											.setAction("android.basic.button.click.pause");
									pause.putExtra("url", url);
									sendBroadcast(pause);
									control.wait();
								} catch (InterruptedException e) {
									e.printStackTrace();
								}
							}
						}

						fileOutputStream.write(buf, 0, ch);
						count += ch;
						// 从字节数组读取数据read(buf)后，返回，读取的个数，count中保存，已下载的数据字节数
						double temp = count / length;
						if (temp >= m) {
							Log.i("TAG", "读取字节循环中的count" + temp);
							m += 0.1;
							load = (int) (count * 100 / length);
							sendMsg(1, load, url, notification, flag, null,
									filename, true);
						}
						// 函数调用handler发送信息
					}
				}
				// 文件输出流为空，则表示下载完成，安装apk文件
				Uri Url = Uri.fromFile(file);
				Log.i("TAG", "下载完成，传递文件位置Url  " + Url);
				sendMsg(2, 0, url, notification, 0, Url, filename, getchanger());
				fileOutputStream.flush();
				if (fileOutputStream != null) {
					fileOutputStream.close();
				}
			} catch (Exception e) {
				e.toString();
				sendMsg(-1, 0, url, notification, 0, null, filename, true);
			}

		}

		public void setSuspend(boolean suspend) {
			this.suspend = suspend;
			if (!suspend) {
				synchronized (control) {
					String filename = geturlfilename(url);
					Log.i("avi", filename + "继续下载   :   " + getSuspend());
					Toast.makeText(getApplicationContext(),
							filename + "继续下载---", Toast.LENGTH_SHORT).show();
					Intent restart = new Intent();
					restart.setAction("android.basic.button.click.restart");
					restart.putExtra("url", url);
					sendBroadcast(restart);
					control.notify();
				}
			}

		}

		public boolean getSuspend() {
			return this.suspend;
		}

		// 设置开关状态
		public void setchanger(boolean changer) {
			this.changer = changer;
		}

		public boolean getchanger() {
			return this.changer;
		}

		public int getflag() {
			return this.flag;
		}

		public String geturl() {
			return this.url;
		}

		public String geturlfilename(String url) {

			String filename;
			int first = url.lastIndexOf("/") + 1;
			filename = url.substring(first, url.length()).toLowerCase();
			return filename;
		}

	}

}
